package ast.FileDemo;

import ast.FilesUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.*;
import org.junit.Test;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Security;
import java.util.*;

public class FileScaner {

    static int count=0;
    private  final Set<String> JRE_JARS = new HashSet(Arrays.asList("rt.jar", "jrt-fs.jar", "android.jar"));

    @Test
    public  void test01() throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        String rootPath = "D:\\codes\\0Java\\230702springlearn\\spring6";
        readFile(rootPath);
        System.out.println(count);
    }

    public  void readFile(String mPath) throws Exception {
        File file = new File(mPath);

        File a= (File) null;
        if(file.isDirectory()){
            String absolutePath = file.getAbsolutePath();
            String[] list = file.list();
            for (String cPath: list) {
                readFile(absolutePath+File.separator+cPath);
            }
        }else {
            //已经是文件了
            if (file.getName().endsWith(".java")){
                readJava(file);
            }
        }
    }

    private  void readJava(File file) throws Exception {
        ASTParser astParser = astParser();
        astParser.setUnitName(file.getName());
        String source = new String(Files.readAllBytes(Paths.get(file.getPath())));
        astParser.setSource(source.toCharArray());
        CompilationUnit astNode;
        try {
            astNode = (CompilationUnit) astParser.createAST(null);
        } catch (Exception e) {
            throw new RuntimeException("ECJ: Unable to parse file.", e);
        }

        countTests(astNode);


    }

    private  void countTests(CompilationUnit astNode) {
        List types = astNode.types();
        for (Object o : types) {
            ASTNode node = (ASTNode)o;
            //只统计类声明下的测试方法
            if(node.getNodeType() == 55){
                TypeDeclaration dc = (TypeDeclaration) node;
                MethodDeclaration[] methods = dc.getMethods();
                for (MethodDeclaration md:methods){
                    List modifiers = md.modifiers();
                    for (Object obj:modifiers) {
                        ASTNode annotaion = (ASTNode)obj;
                        if(annotaion.getNodeType() == 78){
                            MarkerAnnotation ma = (MarkerAnnotation)annotaion;
                            Name typeName = ma.getTypeName();
                            if("Test".equals(typeName.toString())){
                                count++;
                            }
                        }
                    }
                }
            }
        }

    }


    public  ASTParser astParser() {
        ASTParser astParser = ASTParser.newParser(AST.getJLSLatest());
        Map<String, String> options = new HashMap();
        //Setting Compliance Level.
        options.put(JavaCore.COMPILER_COMPLIANCE, Integer.toString(11));//设置java语言版本
        //指定是否使用源代码级别的兼容性
        options.put(JavaCore.COMPILER_SOURCE, Integer.toString(11));
        //每个编译单元报告的最大问题数。
        options.put(JavaCore.COMPILER_PB_MAX_PER_UNIT, "42000");
        //启用对预览语言功能的支持。
        options.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, "disable");

        astParser.setCompilerOptions(options);

        List<File> DEFAULT_CLASSPATH = FilesUtils.getClassPath(FilesUtils.DEFAULT_TEST_JARS_DIRECTORY);

        boolean includeRunningVMBootclasspath = DEFAULT_CLASSPATH.stream()
                .noneMatch(f -> JRE_JARS.contains(f.getName()));

        astParser.setEnvironment(DEFAULT_CLASSPATH.stream()
                .map(File::getAbsolutePath)
                .toArray(String[]::new), new String[]{}, new String[]{}, true);

        astParser.setResolveBindings(true);
        astParser.setBindingsRecovery(true);
        return astParser;
    }
}
